﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Collections;
using System.Threading;
using System.Text.RegularExpressions;

using SistemaCenterQuimPost.Reportes; //usado para imprimir el Traslado
using SistemaCenterQuimPost.Entidad; //usado para generar los archivos.

using System.IO;    //3 referencias que son necesarias para el proceso de archivos.
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Serialization;

namespace SistemaCenterQuimPost.UI.PostCajero
{
    
    public partial class frmTrasladosSalida : SistemaCenterQuimPost.UI.frmTraslado
    {
        //---------------------ATRIBUTOS-------------------
        
        private DataSet2TableAdapters.PostTableAdapter postTa;

        private FileStream trasladoSalida; //clase que maneja la información sobre el archvi y la forma de crearlo.
            
        //--------------------CONSTRUCTORES-----------------

        public frmTrasladosSalida()
        {
            InitializeComponent();

            centerQuimDs = new DataSet2();
            postTa = new DataSet2TableAdapters.PostTableAdapter();

        }

         public frmTrasladosSalida(int ancho, int alto) //frmGestiónProductos usan Administrador y Cajero, ambos usan diferentes 
        //tamaño de ventana. Al usar este formulario se reciben los tamaños de ventana ha usar en cada uno.
        {
            InitializeComponent();

            
            this.Width = ancho;
            this.Height = alto;
            this.MinimumSize = new System.Drawing.Size(ancho, alto); //Se establece el tamaño máximo y mínimo en pixeles.
            this.MaximumSize = new System.Drawing.Size(ancho, alto);

        }

        //---------------ESTADOS---------------------

         //virtual me permite redefinir, en este caso solo en las clases hijas
         protected override void estEsperandoOperacion() //estado luego de realizar una busqueda exitosa, agregar o editar. Es decir con datos en vista.
         {
             estadoDelFormulario = "estEsperandoOperacion";

             System.Windows.Forms.Control[] controlesHabilitados = { this.txtCodBarra, this.btnBusCodigo, this.txtDescripcion, this.btnBusDescripcion };
             System.Windows.Forms.Control[] controlesDeshabilitados = { this.lstProductosCodBarra, this.lstProductosDescripcion };
             System.Windows.Forms.Control[] controlesVisibles = { };
             System.Windows.Forms.Control[] controlesInvisibles = { this.lstProductosCodBarra, this.lstProductosDescripcion, lblError };

             habilitarControles(controlesHabilitados);
             deshabilitarControles(controlesDeshabilitados);
             visibleControles(controlesVisibles);
             invisibleControles(controlesInvisibles);

             if (refrescarResgProductos) //si hace falta actualizar el refrescarResgProducto se realiza
             {
                 ejecutarHiloActualizarResgProductos();

             }

             cargarNombrePost();

             errorProvider1.Clear();  //se borran los errores, si habian.

             txtCodBarra.Focus();   //se deja el foco en txtCodBarra

             cboPostEnviar.SelectedIndex = -1;

             


         }

        //----------------------METODOS VARIOS--------------------------------------
         protected override void limpiarDatos() //Se deja todo los datos vacios, usado al inicio y cada nuevo traslado en la interface
         {
             this.cboTurno.SelectedIndex = 0;
             this.cboPostEnviar.SelectedIndex = -1;
             this.txtCodBarra.Text = "";
             this.txtDescripcion.Text = "";
             this.dgvProductos.Rows.Clear();

         }

         private ArrayList obtenerNombresPost() //obtiene los nombres de los post.
         {
             string[] listaSubcarpetas; //variable que almacenará la lista de todas las subcarpetas dentro de Dropbox.
             listaSubcarpetas = Directory.GetDirectories("C:\\Dropbox"); //obtenemos la lista de las subcarpetas en Dropbox.

             ArrayList nombresPost = new ArrayList(); //creamos un arrayList, que almacenará solo los nombre de los post
             nombresPost.Clear(); //vaciamos el arrayList

             foreach (string unaSubcarpeta in listaSubcarpetas)
             {
                 FileInfo unFileInfo = new FileInfo(unaSubcarpeta); //creamos un FileInfo que almacen
                 if (Regex.Match(unFileInfo.Name, "POST*").Success)
                 {
                     nombresPost.Add(unFileInfo.Name);
                 }
             }

             return (nombresPost);

         }

         private void cargarNombrePost() //carga los nombres de los post en cboPost.
         {
             cboPostEnviar.Items.Clear(); //se vacia el cbo de post
             
             ArrayList listaPost = new ArrayList(); //almacenara los nombres (string) de todos los post, para luego buscar sus nombres de pedidos.

             listaPost = obtenerNombresPost(); //se obtienen todos los nombre de post.

             foreach (string nombrePost in listaPost) //se cargan los nombres de los post en los combos correspondientes
             {
                 cboPostEnviar.Items.Add(nombrePost);
                 
             }

             cboPostEnviar.SelectedIndex = -1; //colocamos el primer items en el comboBox.

         }

        
         protected override void altaTraslado()
         {
             //base.altaTraslado();
             trasladosTa.InsertQueryTraslados(Convert.ToDateTime(obtenerFechaActual()), cboTurno.Text, obtenerCodUsuarioActual(), "S", cboPostEnviar.SelectedItem.ToString().ToUpper());
         }

         protected override void redefenirStock()
         {
             //base.redefenirStock();
             foreach (DataGridViewRow row in dgvProductos.Rows)//recorremos el datagride y actualizamos stock
             {
                 productosTa.FillByCodigoyDescripcion(centerQuimDs.Productos, row.Cells[0].Value.ToString(), row.Cells[1].Value.ToString());

                 double regStock = centerQuimDs.Productos[0].stockActual;

                 if (centerQuimDs.Productos[0].tipo == "B") //si el producto es base
                 {
                     centerQuimDs.Productos[0].stockActual -= Math.Round(Convert.ToDouble(row.Cells[2].Value), 3);
                 }
                 else //si no es base, entonces puede ser un terminado o un producto disuelto vendido por cantidad.
                 {
                     centerQuimDs.Productos[0].stockActual -= Convert.ToInt32(row.Cells[2].Value);
                 }

                 if (centerQuimDs .Productos [0].stockActual < 0) //si el stock que da negativo lo volvemos a cero e informamos el movimiento
                 {
                     centerQuimDs.Productos[0].stockActual  = 0;
                     movimientosTa.InsertQueryMovimientosxProducto(row.Cells[0].Value.ToString(), row.Cells[1].Value.ToString(), Convert.ToDateTime(obtenerFechaActual()), "A", "Stock Negativo en Traslado Nª" + trasladosTa .ScalarQueryTraslados ().ToString (), Convert.ToDecimal(row.Cells[2].Value) - Convert.ToDecimal(regStock));
                 }

                 productosTa.Update(centerQuimDs.Productos);

                 movimientosProductosBajaTraslado(row.Cells[0].Value.ToString(), row.Cells[1].Value.ToString(), Convert.ToDecimal(row.Cells[2].Value));
             }

         }

         protected override void crearArchivoTraslado() //se crea el archivo de traslado y se deja en el post seleccionado.
         {
             postTa.Fill(centerQuimDs.Post); //buscamos el registro de los datos de post.

             int ultimoTraslado = trasladosTa.ScalarQueryTraslados().Value;

             string nombreArchivo = "C:\\Dropbox\\" + cboPostEnviar.Text + "\\Datos del Sistema\\Traslados\\traslado" + centerQuimDs.Post[0].nombre + ultimoTraslado.ToString() + ".cq"; //coloca el nombre del directorio y archivo completo.

             //guardar el archivo a través del objeto FileStream.
             try
             {
                 trasladoSalida = new FileStream(nombreArchivo, FileMode.OpenOrCreate, FileAccess.Write); //abre el archivo con acceso de escritura

                 CargarDatosAlArchivo();

             }

             catch (SerializationException)
             {
                 //notifica al usuario si el archivo no existe
                 MessageBox.Show("Error al escribir en el archivo", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
             }

             catch (FormatException)
             {
                 //notifica al usuario si el archivo no existe
                 MessageBox.Show("Formato inválido", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
             }

             catch (IOException)
             {
                 //notifica al usuario si el archivo no existe
                 MessageBox.Show("Error al abrir el archivo", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
             }
             finally
             {
                 cerrarArchivo();
             }    
         }

         private void CargarDatosAlArchivo()
         {
             //---------ESCRIBIR ENCABEZADO---------------------

             int ultimoTraslado = trasladosTa.ScalarQueryTraslados().Value;


             RegistroTraslado unRegistroTraslado;

             unRegistroTraslado = new RegistroTraslado(obtenerFechaActual(), cboTurno.SelectedItem.ToString(), obtenerNombreUsuarioActual(),cboPostEnviar.SelectedItem.ToString(),ultimoTraslado,centerQuimDs.Post[0].nombre);  //El codRemito se pasa a "cq123"

             //escribe registro al objeto FileStream (serializa el objeto)
             aplicadorFormato.Serialize(trasladoSalida, unRegistroTraslado);

             //----------ESCRIBIR CUERPO-------------------------

             foreach (DataGridViewRow row in dgvProductos.Rows)
             {

                 RegistroProductoTraslado unRegistroProductoTraslado; //instanciamos un registroProductoTraslado(Serializado) y le asignamos nombre.

                 unRegistroProductoTraslado = new RegistroProductoTraslado(Convert.ToString(row.Cells[0].Value), Convert.ToString(row.Cells[1].Value), Convert.ToDouble(row.Cells[2].Value));

                 //escribe registro al objeto FileStream (serializa el objeto)
                 aplicadorFormato.Serialize(trasladoSalida, unRegistroProductoTraslado);


             }

         }

         protected override void imprimir()
         {
             //base.imprimir();
            //buscamos el registro del ultimo traslado y sus productos
             int ultimoTraslado = trasladosTa.ScalarQueryTraslados().Value;
             trasladosTa .FillByCodigoTraslado (centerQuimDs .Traslados ,ultimoTraslado );
             productosXTrasladosTa.FillByCodigoTraslado(centerQuimDs.ProductosxTraslado, ultimoTraslado);

           //Creamos una instancia de un objeto DataTable, y le hacemos que referencie a la tabla en CenterQuimDs.productoXTraslado
             DataTable unaDataTable = new DataTable();
             unaDataTable = centerQuimDs.ProductosxTraslado;

             //busamos datos del post

             postTa.Fill(centerQuimDs.Post);

             //creamos una instancia del tipo CrystalReports que habiamos creado y le asignamos a su crTrasladoSalida la tabla instanciada y parametros necesarios.
             crTrasladoSalida unCrTraslado = new crTrasladoSalida();
             unCrTraslado.SetDataSource(unaDataTable);

             unCrTraslado.SetParameterValue("fechaValor", centerQuimDs.Traslados[0].fechaTraslado.ToString("d"));
             unCrTraslado.SetParameterValue("cajeroValor", obtenerNombreUsuarioActual().ToString());
             unCrTraslado.SetParameterValue("turnoValor", centerQuimDs.Traslados[0].turnoTraslado);
             unCrTraslado.SetParameterValue("postDestinoValor", centerQuimDs.Traslados[0].post);
             unCrTraslado.SetParameterValue("unaDireccion", centerQuimDs.Post[0].dirección );
             unCrTraslado.SetParameterValue("unTelefono", centerQuimDs.Post[0].telefono);

             //creamos una instancia del frmReporteTraslado y le asignamos a su CrystalReportViewer el CrystalReports seteado
             frmReporteTraslado unFrmReporteTraslado = new frmReporteTraslado();
             unFrmReporteTraslado.crvReporteSalida.ReportSource = unCrTraslado;

             //mostramos el frmReporteVenta
             unFrmReporteTraslado.ShowDialog();
         }

        private void movimientosProductosBajaTraslado (string codigo, string nombre, decimal cantidad)
         {
             movimientosTa.InsertQueryMovimientosxProducto(codigo, nombre, Convert.ToDateTime(obtenerFechaActual()), "B", "Traslado Salida Nº" + trasladosTa.ScalarQueryTraslados().ToString(), cantidad);
         }

        private void cerrarArchivo()
        {
            try
            {
                
                if (trasladoSalida != null)  //determina si existe el archivo
                {
                    trasladoSalida.Close();  //cierra el archivo
                }
            }
            catch (IOException)  //notifica al usuario del error al cerrar el archivo
            {
                MessageBox.Show("No se puede cerrar el archivo.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);

            }
        }
    }
}
